#ifndef __CH438_H__
#define __CH438_H__


/* 
** hardware interface
** E17:CS, E16:RD, E15:WR
** E14~E08: Address
** E07~E00: Data 
*/

#define CH438_BASE  (SUNXI_PIO_PBASE+0x90) /* PE base */

#define CH438_CFG0  (ch438_membase+0x00) /* PE Configure Register 0, PE7~PE0 */
#define CH438_CFG1  (ch438_membase+0x04) /* PE Configure Register 1, PE15~PE8 */
#define CH438_CFG2  (ch438_membase+0x08) /* PE Configure Register 2, PE17~PE16 */
#define CH438_CFG3  (ch438_membase+0x0C)
#define CH438_DAT   (ch438_membase+0x10) /* PE Data Register, PE17~PE0 */
#define CH438_DRV0  (ch438_membase+0x14) /* PE Multi-Driving 0, PE15~PE0 */
#define CH438_DRV1  (ch438_membase+0x18) /* PE Multi-Driving 1, PE17~PE16 */
#define CH438_PULL0 (ch438_membase+0x1C) /* PE Pull 0, PE15~PE0 */
#define CH438_PULL1 (ch438_membase+0x20) /* PE Pull 1, PE17~PE16 */

#define GPIO_RANGE  0x24

#define CH438_CS    17
#define CH438_RD    16
#define CH438_WR    15

struct ch438_pin {
	int rst,pint;
	int irqnum;
};

struct ch438_port {
	struct uart_port port;
	char           name[16];

	unsigned char  id;
	unsigned char  acr;
	unsigned char  ier;
	unsigned char  lcr;
	unsigned char  mcr;
	unsigned char  fcr;
	unsigned char  dll;
	unsigned char  dlh;

	unsigned char  msr_saved_flags;
	unsigned int   lsr_break_flag;

	unsigned int io_num;
	struct ch438_pin *pin;
};

#define CH438_MEM_BASE  SUNXI_GPIOE_BASE

#define RBR_RO        0x00      /* Received Buffer Register */
#define THR_WO        0x00      /* Transmit Holding Register */
#define IER_RW        0x01      /* Interrupt Enable Register */
#define IIR_RO        0x02      /* Interrupt Identification Register */
#define FCR_WO        0x02      /* FIFO Control Register */
#define LCR_RW        0x03      /* Line Control Register */
#define MCR_RW        0x04      /* Modem Control Register */
#define LSR_RO        0x05      /* Line Status Register */
#define MSR_RO        0x06      /* Modem Status Register */
#define SCR_RW        0x07      /* Scratch Register */
#define DLL_RW        0x00      /* Divisor latch (LSB) */
#define DLH_RW        0x01      /* Divisor latch (MSB) */
 
/* CH438 inside uart0~7 Status Register */
 
#define SSR_RO        0x4F       /* all interrupt status */
 
/* IER register bits */
 
#define BIT_IER_RESET       BIT(7)      /* 1: reset */
#define BIT_IER_LOWPWR      BIT(6)      /* 1: close inside base clk */
#define BIT_IER_SLP			BIT(5)      /* 1: SLP[uart0] */
#define BIT_IER_CK2X		BIT(5)		/* 1: CK2X[uart1~7]*/	
#define BIT_IER_MSI         BIT(3)      /* 1: enable MODEM status change interrupt */
#define BIT_IER_RLSI        BIT(2)      /* 1: enable receive line state interrupt */
#define BIT_IER_THRI        BIT(1)      /* 1: enable transmit is null interrupt */
#define BIT_IER_RDI         BIT(0)      /* 1: enable receive data interrupt */
 
/* IIR Interrupt ID Register */
#define BIT_IIR_FIFOENS1    BIT(7)		/* FIFOs is used */
#define BIT_IIR_FIFOENS0    BIT(6)      /* FIFOs is used */
/* interrupt type:*/
#define BIT_IIR_IID3        BIT(3)
#define BIT_IIR_IID2        BIT(2)      
#define BIT_IIR_IID1        BIT(1)      
#define BIT_IIR_NOINT       BIT(0)
#define   BIT_IIR_IID_MASK	    (BIT(3)|BIT(2)|BIT(1)|BIT(0))
#define   BIT_IIR_FEFLAG_MASK   (BIT(7)|BIT(6))

/* Interrupt ID */
#define   INT_MODEM_CHANGE  0x00      /* MODEM input change */
#define   INT_NOINT         0x01      /* none interrupt */
#define   INT_THR_EMPTY     0x02      /* THR is empty */
#define   INT_RCV_SUCCESS   0x04      /* receive success */
#define   INT_RCV_LINES     0x06      /* receive line status */
#define   INT_RCV_OVERTIME  0x0C      /* receive overtime */

/* FIFO Control Register */
/* Trigger Point: 00:1Byte, 01:16Byte, 10:64Byte, 11:112Byte */
#define BIT_FCR_RECVTG1     BIT(7)      /* Receiver TriGger 1 */
#define BIT_FCR_RECVTG0     BIT(6)      /* Receiver TriGger 0 */
#define   BIT_FCR_FT_112	(BIT(7)|BIT(6))
#define   BIT_FCR_FT_64		BIT(7)
#define   BIT_FCR_FT_16		BIT(6)
#define   BIT_FCR_FT_01		0x00
 
#define BIT_FCR_TFIFORST    BIT(2)      /* Transmit FIFO Reset */
#define BIT_FCR_RFIFORST    BIT(1)      /* Receive FIFO Reset */
#define BIT_FCR_FIFOEN      BIT(0)      /* FIFO Enable */
 
/* Line Control Register */
/* DLAB: 1:read/write DLL/DLH, 0:read/write RBR/THR/IER */ 
#define BIT_LCR_DLAB        BIT(7)      
#define BIT_LCR_SBC			BIT(6)      /* 1:create BREAK */
 
/* Parity Format: when PAREN=1, 00:ODD,01:EVEN,10:MARK,11:SPACE */
#define BIT_LCR_PARMODE1    BIT(5)      /* Set Parity Style */
#define BIT_LCR_PARMODE0    BIT(4)      /* Set parity Style */
#define   BIT_PARITY_MASK     (BIT(5)|BIT(4))    /* Parity Mask */
#define   BIT_LCR_EPAR	      (1<<4)    /* Parity EVEN */
#define   BIT_LCR_OPAR	      (0<<4)    /* Parity ODD */
 
#define BIT_LCR_PARITY      BIT(3)      /* 1:enable Parity */
#define BIT_LCR_STOP        BIT(2)      /* 1:2StopBits, 0:1StopBits */
/* Set WrodLen: 00:5, 01:6, 10:7, 11:8 */
#define BIT_LCR_WORDSZ1     BIT(1)      /* Word Length Select Bit1 */
#define BIT_LCR_WORDSZ0     BIT(0)		/* Word Length Select Bit0 */
#define   BIT_LCR_WLEN_MASK   (BIT(1)|BIT(0))
#define   BIT_LCR_WLEN_8      0x03
#define   BIT_LCR_WLEN_7      0x02
#define   BIT_LCR_WLEN_6      0x01
#define   BIT_LCR_WLEN_5      0x00
 
/* Modem Control Register */
#define BIT_MCR_AFE         BIT(5)      /* 1:enable CTS/RTS */
#define BIT_MCR_LOOP        BIT(4)      /* 1:enable Loop-back mode */
#define BIT_MCR_OUT2        BIT(3)      /* 1:enable irq hw output !!! */
#define BIT_MCR_OUT1        BIT(2)      /* user defined output bit */
#define BIT_MCR_RTS         BIT(1)      /* Reauest to Send */
#define BIT_MCR_DTR         BIT(0)      /* Data Terminal Ready */
 
/* Line Status Register */
#define BIT_LSR_RXFIFOE		BIT(7)      /* Receive FIFO Error */
#define BIT_LSR_TEMT        BIT(6)      /* Transmit Empty */
#define BIT_LSR_THRE        BIT(5)      /* Transmit Holding Register Empty */
#define BIT_LSR_BI			BIT(4)      /* Break Interrupt */
#define BIT_LSR_FE			BIT(3)      /* Framing Error */
#define BIT_LSR_PE			BIT(2)      /* Parity Error */
#define BIT_LSR_OE			BIT(1)      /* Overrun Error */
#define BIT_LSR_DR			BIT(0)      /* Data Ready */

#define LSR_BRK_ERROR_BITS	0x1E	    /* BI|FE|PE|OE bits */
 
/* Modem Status Register */
#define BIT_MSR_DCD         BIT(7)      /* Data Carrier Detect */
#define BIT_MSR_RI          BIT(6)      /* Ring Indicator */
#define BIT_MSR_DSR         BIT(5)      /* Data Set Ready */
#define BIT_MSR_CTS         BIT(4)      /* Clear to Send */
#define BIT_MSR_DDCD        BIT(3)      /* Delta Data Carrier Detect */
#define BIT_MSR_TERI        BIT(2)      /* Trailing Edge Ring Indicator */
#define BIT_MSR_DDSR        BIT(1)      /* Delta Data Set Ready */
#define BIT_MSR_DCTS        BIT(0)      /* Delta Clear to Send */
#define BIT_MSR_ANY_DELTA	0x0F
#define MSR_SAVE_FLAGS BIT_MSR_ANY_DELTA
 
#define CH438_IIR_FIFOS_ENABLED 0xC0  /* enable FIFO */

#endif
